package ru.spb.xmlreshelper.database;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.spb.xmlreshelper.domain.DatabaseException;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

/**
 * Oracle database connection manager
 *
 * @author Nikita.Brazhnikov
 */
public class DatabaseManager {

    private static final Logger logger = LoggerFactory.getLogger(DatabaseManager.class);

    private String url;
    private String port;
    private String sid;
    private String username;
    private String password;

    private Map<String, String> params = Maps.newTreeMap();

    public static final DatabaseManager instance = new DatabaseManager();

    private DatabaseManager() {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static DatabaseManager getInstance() {
        return instance;
    }

    public Connection getConnection() throws DatabaseException {
        final Properties connProp = new Properties();
        connProp.put("user", username);
        connProp.put("password", password);
        final String connString = getConnectionString();
        logger.debug("Connection params: {} {}@{}", connString, username, password);
        try {
            Connection con = DriverManager.getConnection(connString, connProp);
            logger.debug("Connected to database");
            return con;
        } catch (SQLException sqle) {
            throw new DatabaseException(sqle);
        }
    }

    public String getConnectionString() {
        return String.format("jdbc:oracle:thin:@%s:%s:%s", url, port, sid);
    }

    public void setParamsMap(Map<String,String> paramsMap) {
        paramsMap = new TreeMap<>(paramsMap);
        url = paramsMap.get("Url");
        sid = paramsMap.get("SID");
        username = paramsMap.get("Username");
        password = paramsMap.get("Password");
        port = paramsMap.get("Port");
    }

    public Map<String,String> getParamsMap() {
        return ImmutableMap.copyOf(params);
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
        params.put("Url", url);
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
        params.put("Port", port);
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
        params.put("Sid", sid);
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
        params.put("Username", username);
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
        params.put("Password", password);
    }
}
